﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace BigPixels
{
    public partial class Palette : UserControl
    {
        public event EventHandler<ColourSelectEventArgs> PaintColourSelected;
        public event EventHandler<ColourSelectEventArgs> CanvasColourSelected;

        public Palette()
        {
            InitializeComponent();

            this.DoubleBuffered = true;
            this.Grid = new PixelGrid(5, 20, this.ClientRectangle); // 128, 128;
            this.PaintColour = Color.Black;
            this.CanvasColour = Color.White;
        }

        public PixelGrid Grid
        {
            get;
            private set;
        }

        public void SetColours(IList<PixelValue> colours)
        {
            int index = 0;
            for (int y = 0; y < this.Grid.GridSize.Height; ++y)
            {
                for (int x = 0; x < this.Grid.GridSize.Width; ++x)
                {
                    if (index < colours.Count)
                    {
                        this.Grid[x, y].Pixel = new PixelValue(colours[index++].Value);
                    }
                    else
                    {
                        this.Grid[x, y].Pixel.Value = Color.Empty;
                    }
                }
            }

            this.Invalidate();
        }

        public List<PixelValue> GetColours()
        {
            var colours = new List<PixelValue>();

            for (int y = 0; y < this.Grid.GridSize.Height; ++y)
            {
                for (int x = 0; x < this.Grid.GridSize.Width; ++x)
                {
                    if (this.Grid[x, y].Pixel.Value != Color.Empty)
                        colours.Add(new PixelValue(this.Grid[x, y].Pixel.Value));
                }
            }

            return colours;
        }

        private void DrawPixels(Graphics g)
        {
            for (int x = 0; x < this.Grid.GridSize.Width; ++x)
            {
                for (int y = 0; y < this.Grid.GridSize.Height; ++y)
                {
                    var cell = this.Grid[x, y];
                    using (var brush = new SolidBrush(cell.Pixel.Value))
                    {
                        g.FillRectangle(brush, cell.Bounds);
                    }
                }
            }
        }

        private void DrawGrid(Graphics g)
        {
            using (var pen = new Pen(Color.LightGray))
            {
                for (int x = 0; x < this.Grid.GridSize.Width; ++x)
                {
                    for (int y = 0; y < this.Grid.GridSize.Height; ++y)
                    {
                        var cell = this.Grid[x, y];
                        g.DrawRectangle(pen, cell.Bounds);
                    }
                }
            }
        }

        private void Palette_Paint(object sender, PaintEventArgs e)
        {
            var graphics = e.Graphics;

            this.Grid.UpdateBounds(this.ClientRectangle);

            DrawPixels(graphics);
            DrawGrid(graphics);
        }

        private void Palette_MouseDown(object sender, MouseEventArgs e)
        {
            try
            {
                var cell = this.Grid.At(e.Location, this.ClientRectangle);

                // colour is not currently valid - pick one...
                if (!cell.Pixel.IsValid)
                {
                    using (var dlg = new ColorDialog())
                    {
                        if (dlg.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
                        {
                            cell.Pixel.Value = dlg.Color;
                            this.Invalidate();
                        }
                    }
                }

                if (cell.Pixel.IsValid)
                {
                    if (e.Button == System.Windows.Forms.MouseButtons.Left)
                    {
                        this.PaintColour = cell.Pixel.Value;

                        var selected = PaintColourSelected;

                        if (selected != null)
                            selected(this, new ColourSelectEventArgs(this.PaintColour));
                    }
                    else if (e.Button == System.Windows.Forms.MouseButtons.Right)
                    {
                        this.CanvasColour = cell.Pixel.Value;

                        var selected = CanvasColourSelected;

                        if (selected != null)
                            selected(this, new ColourSelectEventArgs(this.CanvasColour));
                    }
                }
            }
            catch (ArgumentOutOfRangeException)
            {
            }
        }

        public Color PaintColour
        {
            get;
            set;
        }

        public Color CanvasColour
        {
            get;
            set;
        }
    }
}
